package com.example.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.jwt.JWTUtil;
import com.example.dao.UserMapper;
import com.example.model.User;
import com.example.service.LoginService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class LoginServiceImpl implements LoginService {

    private final static Logger logger =
            LoggerFactory.getLogger(LoginServiceImpl.class);
    @Autowired
    UserMapper userMapper;

    /**
     * 传参是String类型的username，怎么拿到User类型的username？
     * 将String类型的username赋值给User user对象中成员变量username
     * new
     * */
    /**
     * 调用方法时，只需要匹配类型，而不是匹配参数名称
     * 调用dao层的方法时，传的参数应该时user而不是username，
     * user指user类型的user，username指string类型的username
     * 更不能是String类型的user，单纯的改变参数名，并不能改变类型不一致的错误
     *
     * Java是强类型的语言，有强制类型一致的要求，传参需要string类型，不能需要object类型，
     * 传参需要类类型的User，不能传类类型的QueryParam，所谓类类型即类型为一种类，例如实体类
     * 而类名编码规范要求首字母大写，其余部分驼峰，类名的大写也是区分类型和-对像名，参数名的关键
     * 首字母大写的是类型，小写的是参数或对象名
     *
     *  当类型不一致时，就需要类型转换，一般是实体类之间的类型转换，
     *  例如Student转换为 QueryParam，最简单的做法是创建一个QueryParam类型的对象，再将Student类型
     *  的对象赋给QueryParam的对象，伪代码如下
     *
     * QueryParam queryParam =  new QueryParam();
     *  queryParam.setParam1(student.getName())
     *  queryParam.setParam2(student.getPassword())
     *
     *  get,set    get 方法获取该对象内部的成员变量值，set方法将参数赋值给对象内部的成员值
     *  实体类最主要的重用就是将参数存储为对象的成员变量值（是对象才有成员变量，而不是类型）
     *  或者根据自身的成员变量值转化为其他类型，例如Student转化为QueryParam
     *  toString常用于将实体类对象的值全部拼接在一起为字符串
     * */
    @Override
    public Map<String, String> login(String voUsername,String voPassword) {
        /**
         * new User*/
        final User user = new User();
       /**
        * set username 将String类型的username转化为User类型的username*/
        user.setUserName(voUsername);
        /**
         * 将username包装为实体类后，传个dao，在数据库中查对应的数据记录，返回值也是User表中的记录
         * 该记录被ORM映射为该实体类的对象*/
        final User userDO = userMapper.selectByUKey(user);
        logger.info("userDO:{}",userDO );
        Assert.notNull(userDO,"用户不存在，不存在的用户名为:{}",
                voUsername);
        /**
         * 从数据库中查出来的记录中获取的密码和前端传过来的密码是否一致，对象之间的比较使用==
         * String之间的比较使用equals*/

    /**
     * 向实体类中获取数据用get方法，一般为get属性名，向实体类中填充数据，一般用set方法，一般为set属性名
     * */

        final String doPassword = userDO.getPassword();
        final HashMap<String, String> data = new HashMap<>(1);
        /**
         * equals比较时，一般用确定的值.equals(xx) 避免null.equals造成空指针*/
        if (! voPassword.equals(doPassword)) {
         throw new IllegalArgumentException("登入失败，密码或用户名不正确");
        }
        data.put("token",getToken(voUsername,voPassword)) ;
        return data;
    }
    public  String getToken(String username,String password ) {
        Map<String, Object> map = new HashMap<>(2) ;
        map.put("username",username);
        map.put("password",password);
        return JWTUtil.createToken(map, "12345".getBytes());
    }
}
